package com.nulldev.util.web.HttpServer3.pages.v3;

import java.io.InputStream;

import com.nulldev.util.io.IOUtils;
import com.nulldev.util.logging.Logger;
import com.nulldev.util.logging.LoggerFactory;
import com.nulldev.util.web.HttpServer3.ReadRequest;
import com.nulldev.util.web.HttpServer3.legacyPages.v1.RequestType;
import com.nulldev.util.web.HttpServer3.pages.v3.HttpPage3.EnhancedSecurityChecks;
import com.nulldev.util.web.urlDetector.detection.UrlDetector;
import com.nulldev.util.web.urlDetector.detection.UrlDetectorOptions;

public class HttpPageRequestValidator {

	private static final Logger log = LoggerFactory.getLogger();

	/**
	 * Checks the request integrity, if supported.
	 * 
	 * @param page
	 * @returns TRUE if a check has failed.
	 */
	public static boolean checkSecurity(final RequestType type, final ReadRequest rr, final HttpPage3 page) {
		if (page == null || !page.hasChecks())
			return false;
		for (final EnhancedSecurityChecks check : page.getChecks()) {
			switch (check) {
				case ONLY_ALLOW_BASIC_METHODS:
					if (!type.equals(RequestType.GET) && !type.equals(RequestType.POST) && !type.equals(RequestType.HEAD) && !type.equals(RequestType.OPTIONS))
						return true;
					break;
				case POST_DATA_NO_URLS: {
					if (rr.length() == 0)
						break;
					final InputStream stream = rr.stream();
					if (!stream.markSupported())
						break;
					try {
						final byte[] initialChunk = new byte[IOUtils.MEMORY_ALLOC_BUFFER];
						stream.mark(IOUtils.MEMORY_ALLOC_BUFFER);
						IOUtils.readFully(stream, initialChunk, 0, IOUtils.MEMORY_ALLOC_BUFFER);
						stream.reset();
						if (new UrlDetector(new String(initialChunk), UrlDetectorOptions.Default).detect().size() > 0)
							return true;
					} catch (Exception ex) {
						log.error("Failed to run POST_DATA_NO_URLS check!", ex);
					}
					break;
				}
				case DISALLOW_POST_DATA:
					if (rr.length() != 0)
						return true;
					break;
				case REQUIRE_AUTHORIZATION_HEADER:
					if (!rr.header("Authorization"))
						return true;
					break;
				case DISALLOW_PROXIES:
					if (rr.header("X-Forwarded-For") || rr.header("Forwarded") || rr.header("Via") || rr.header("Proxy-Authorization")
							|| rr.header("X-Forwarded-Host"))
						return true;
					break;
				default:
					log.warn("Unknown check: " + check);
					break;
			}
		}
		return false;
	}
}
